/****************************************************************
 *  This file created by writerB.php on 03/20/2007 at 23:03:46  *
 ****************************************************************
 *  writerB.php created by Tonk (tonk@ctonk.com) in 2007        *
 ****************************************************************
 *                 General Document Information
 *
 *  File Name: board.cpp
 *  Class Name: Board
 *  Data members: 4
 *  Notes:
 ****************************************************************/

#include <cstring>
#include <fstream>
#include <iostream>
#include <vector>
#include "board.h"
#include "definitions.h"
#include "log.h"
#include "note.h"
#include "stringutil.h"



unsigned Board::numBoards = 0;
unsigned Board::boardIndex = 0;


// Default constructor...
Board::Board() {
	setBoardID( ++boardIndex );
	setNumber( 0 );
	setLevel( 0 );
	// Increment the object count...
	numBoards++;
}

// Additional constructors...

// Copy constructor (Doesn't change _BoardID)...
Board::Board( const Board& ref ) {
	setBoardID( ++boardIndex );
	setNumber( ref.getNumber() );
	setLevel( ref.getLevel() );
	setName( ref.getName() );
	// Increment the object count...
	numBoards++;
}

// Destructor...
Board::~Board() {
	for ( std::vector< Note* >::iterator it = getNotes().begin(); it != getNotes().end(); ) {
		delete (*it);
		it = getNotes().erase( it );
	}
	// Decrement the object count...
	numBoards--;
}

// Assignment operator (Doesn't change _BoardID)...
Board& Board::operator = ( const Board& ref ) {
	setNumber( ref.getNumber() );
	setLevel( ref.getLevel() );
	setName( ref.getName() );
	return *this;
}

// Equality operator (Compares _number)...
bool Board::operator == ( const Board& ref ) const {
	return	( getNumber() == ref.getNumber() );
}

// Inequality operator (Compares _number)...
bool Board::operator != ( const Board& ref ) const {
	return	( getNumber() != ref.getNumber() );
}

// Less than operator (Compares _number)...
bool Board::operator < ( const Board& ref ) const {
	return ( getNumber() < ref.getNumber() );
}

// Greater than operator (Compares _number)...
bool Board::operator > ( const Board& ref ) const {
	return ( getNumber() > ref.getNumber() );
}

// Protected Methods...
void Board::setBoardID( const int& BoardID ) { // protected
	_BoardID = BoardID;
}

// Public accessor methods...
int Board::getBoardID( void ) const { // public
	return _BoardID;
}

void Board::setNumber( const unsigned& number ) { // public
	_number = number;
	return;
}

unsigned Board::getNumber( void ) const { // public
	return _number;
}

void Board::setLevel( const unsigned& level ) { // public
	_level = level;
	return;
}

unsigned Board::getLevel( void ) const { // public
	return _level;
}

void Board::setName( const std::string& name ) { // public
	_name = name;
	_file = BOARD_DIR + getName() + ".board";
	return;
}

std::string Board::getName( void ) const { // public
	return _name;
}

std::string Board::getFile( void ) const { // public
	return _file;
}

std::vector< Note* >& Board::getNotes( void ) { // public
	return _notes;
}

// General methods...
Note* Board::addNote( void ) { // public
	Note* note = new Note;
	getNotes().push_back( note );
	return note;
}

void Board::initialize( const unsigned& number, const unsigned& level, const std::string& name ) { // public
	setNumber( number );
	setLevel( level );
	setName( name );	// setName() is a "set" method for _name and _file
	return;
}

void Board::load() { // public
	char temp[100000];
	std::ifstream read( getFile().c_str() );

	if ( read.fail() ) {
		std::string message;
		message << "Couldn't open " << getFile() << " for reading.";
		log( message, SERVER );
		return;
	}

	while ( read.peek() != EOF ) {
		read.getline( temp, 100000 );
		if ( strcmp( temp, "**NOTE" ) == 0 ) {
			read >> addNote();
			continue;
		}
	}

	read.close();
	read.clear();

	return;
}

void Board::save( void ) { // public
	std::ofstream write( getFile().c_str() );

	// Save notes in sequence...
	for ( unsigned i = 0; i < (unsigned)Note::noteIndex; i++ )
		for ( std::vector< Note* >::iterator it = getNotes().begin(); it != getNotes().end(); it++ )
			if ( (*it)->getId() == i )
				write << *it;

	write.close();
	write.clear();

	return;
}

// Static methods...

// Associated operators...
std::ostream& operator << ( std::ostream& write, Board& board ) { // associated
	write << board.getNumber() << ' ' << board.getLevel() << ' ' << board.getName() << ' ' << board.getFile() << '\n';
	for ( std::vector< Note* >::iterator it = board.getNotes().begin(); it != board.getNotes().end(); it++ )
		write << *it;
	return write;
}

std::ostream& operator << ( std::ostream& write, Board* board ) { // associated
	return ( write << *board );
}
